using System;
using System.Collections;
using System.Html;
using System.Runtime.CompilerServices;
using jQueryApi;

[Mixin("jQuery.fn")]
public static class ExpandoPlugin
{
    public static jQueryObject Expando(ExpandoOptions customOptions)
    {
        string leftMark = "&#x25C4;";
        string rightMark = "&#x25BA;";
        string downMark = "&#x25BC;";
        string eMarkClass = "expandoPluginMark";

        ExpandoOptions defaultOptions =
            new ExpandoOptions(
                "side", "left",
                "initiallyClosed", true,
                "fullSurface", false
            );

        ExpandoOptions options =
            jQuery.ExtendObject<ExpandoOptions>(new ExpandoOptions(), defaultOptions, customOptions);

        if (Script.IsNullOrUndefined(options.openMark))
            options.openMark = downMark;

        if (Script.IsNullOrUndefined(options.closedMark))
            options.closedMark = options.side == "left" ? rightMark : leftMark;

        return jQuery.Current.Each(delegate(int i, Element element)
        {

            jQueryObject expando = jQuery.FromHtml("<span/>").CSS(new Dictionary(
                "color", "#008",
                "padding", (options.side == "left" ? "0 5px 0 0" : "0 0 0 5px")
            )).AddClass(eMarkClass).Html(options.initiallyClosed ? options.closedMark : options.openMark);

            options.clickOpen = delegate(jQueryEvent e)
            {
                jQuery.This.Unbind("click").Click(options.clickClosed).Closest("dl").Children("dd").Show();
                jQuery.This.Parent().Find("." + eMarkClass).Html(options.openMark);
                e.StopImmediatePropagation();
                e.PreventDefault();
            };
            options.clickClosed = delegate(jQueryEvent e)
            {
                jQuery.This.Unbind("click").Click(options.clickOpen).Closest("dl").Children("dd").Hide();
                jQuery.This.Parent().Find("." + eMarkClass).Html(options.closedMark);
                e.StopImmediatePropagation();
                e.PreventDefault();
            };

            if (options.side == "left")
                expando.PrependTo(jQuery.This.Children("dt"));
            else
                expando.AppendTo(jQuery.This.Children("dt"));

            (options.fullSurface ? expando.Parent() : expando).Click(delegate(jQueryEvent e)
            {
                jQueryObject dd = jQuery.This.Closest("dt").Next("dd");
                if (dd.Is(":visible"))
                    ((Function)(object)options.clickClosed).Call(jQuery.Element, e);
                else
                    ((Function)(object)options.clickOpen).Call(jQuery.Element, e);
            }).CSS("cursor", "pointer");

            if (options.initiallyClosed)
                jQuery.This.Children("dd").Hide();
            else
                jQuery.This.Children("dd").Show();
        });
    }

}

[Imported]
[ScriptName("Object")]
public sealed class ExpandoOptions
{
    public string side;
    public bool initiallyClosed;
    public bool fullSurface;
    public string openMark;
    public string closedMark;
    public jQueryEventHandler clickOpen;
    public jQueryEventHandler clickClosed;

    public ExpandoOptions()
    {
    }

    public ExpandoOptions(params object[] nameValuePairs)
    {
    }
}

#region Script# Support
[Imported]
public sealed class ExpandoObject : jQueryObject
{
    public jQueryObject Expando()
    {
        return null;
    }

    public jQueryObject Expando(ExpandoOptions options)
    {
        return null;
    }
}
#endregion
